let promise = (middlewareAPI) => {
  return next => {
    return action => {
      console.log('promise')
      next(action)
    }
  }
}

let thunk = middlewareAPI => { // middlewareAPI 层
  return next => { // next 层
    return action => { // action 层
      console.log('thunk')
      next(action)
    }
  }
}

let logger = middlewareAPI => { // middlewareAPI 层
  return next => { // next 层
    return action => { // action 层
      console.log('logger')
      next(action)
    }
  }
}

// 把所有的 redux 中间件放到 chain 中
const chain = [promise, thunk, logger].map(fn => fn({}))

const dispatch = (action) => {
  console.log('原始的 dispatch 方法', action)
}

function compose(funcs) {
  return function (args) {
    for (let i = funcs.length - 1; i >= 0; i--) {
      // 将每个中间件的 action 层作为参数传递给下一个中间件的 next 层当作参数
      // 将循环中最后一个中间件传递给外界当作组合后的 dispatch 
      args = funcs[i](args)
    }
    return args
  }
}

const composed = compose(chain)

const newDispatch = composed(dispatch)
newDispatch({ type: 'ADD' })

/**
 * 组合逻辑
 * 1. 生成一个 chain 数组 里面保存的每一个函数都包含一个中间件 next 层的逻辑
 * 2. 调用 compose 方法时将 chain 数组作为参数传递 返回 composed 函数
 * 3. 调用 composed 函数将原生 dispatch 函数作为参数传递 ( 组合核心 ) 返回一个 newDispatch 函数
 *     1. 调用最后一个 logger 中间件 next 层时传递原生 dispatch 函数 返回 logger 中间件的 action 层
 *     2. 调用 thunk 中间件的 next 层时传递了 logger 中间件的 action 层作为参数 返回 thunk 中间件的 action 层
 *     3. 调用 promise 中间件的 next 层时传递了 logger 中间件的 action 层作为参数 返回 promise 中间件的 action 层
 * 
 * 运行逻辑
 * 4. 调用 newDispatch 函数时传递 action 动作对象
 *     1. 执行 promise 中间件的 action 层时将 action 动作对象作为参数传递
 *     2. 执行 thunk 中间件的 action 层时将 action 动作对象作为参数传递
 *     3. 执行 logger 中间件的 action 层时将 action 动作对象作为参数传递
 *     4. 执行 dispatch 派发动作的函数将 action 动作对象作为参数传递
 * 
 * 
 */
